#include "pch.hh"

#include "common/Base.hh"

#include <yaml-cpp/yaml.h>

namespace common {

Base *UniqueBase::loadField(uint64_t field, const std::string &value) {
    switch (field) {
    FIELD_INT(uid, uid_);
    FIELD_STR(name, name_);
    }
    return nullptr;
}

static inline void loadNode(const YAML::Node &node, common::Base *data) {
    for (const auto &p: node) {
        switch (p.second.Type()) {
        case YAML::NodeType::Scalar:
            data->loadField(h64_(p.first.Scalar()), p.second.Scalar());
            break;
        case YAML::NodeType::Sequence:
        {
            for (const auto &p2 : p.second) {
                switch (p2.Type()) {
                case YAML::NodeType::Map:
                {
                    common::Base *subdata = data->loadField(h64_(p.first.Scalar()), "");
                    if (subdata == nullptr) continue;
                    loadNode(p2, subdata);
                    break;
                }
                case YAML::NodeType::Scalar:
                    data->loadField(h64_(p.first.Scalar()), p2.Scalar());
                    break;
                }
            }
            break;
        }
        case YAML::NodeType::Map:
        {
            common::Base *subdata = data->loadField(h64_(p.first.Scalar()), "");
            if (subdata == nullptr) break;
            loadNode(p.second, subdata);
            break;
        }
        }
    }
}

void Base::load(const std::string & filename, const std::string & child) {
    YAML::Node root = YAML::LoadFile(filename);
    YAML::Node node = root[child];
    if (!node.IsDefined()) return;
    loadNode(node, this);
}

void BaseMgrLoader::load(const std::string &filename) {
    std::vector<YAML::Node> nodes = YAML::LoadAllFromFile(filename);
    for (auto &node: nodes) {
        if (!node.IsSequence()) continue;
        for (const auto &p: node) {
            if (!p.IsMap()) continue;
            auto data = newBase();
            if (!data) continue;
            loadNode(p, data);
            if (data->loaded())
                addBase(data);
            else
                delete data;
        }
    }
    loaded();
}

}
